<?php

include_once('MIME/Type.php');

class FRM_StaticContentController extends FRM_Controller
{
	/**
	 * The root directory to find resources to server
	 */
	protected $_root_dir = '';

	/**
	 * Constructor
	 *
	 * simply initialize the _root_dir member
	 */
	public function __construct()
	{
		$this->_root_dir = realpath(FRAMEWORK_DIR.'/resources');
	}

	/**
	 * *Magic* function for all actions
	 * @link http://php.net/__call
	 *
	 * Basically, the only action here is serving the content
	 * so we use the action name (that we got from the Request)
	 * as the first subdir (domain) and the original args string
	 * as the rest of the path to the file.
	 *
	 * The file path is then sanitized, and the file is served
	 * with an autodetected mime-type if it exists.
	 *
	 * In case the file doesn't exist or cannot be accessed, an exception is thrown
	 *
	 * @param string from __call signature, unused, see link
	 * @param array from __call signature, unused, see link
	 * @throw FRM_Exception if the file is not found or cannot
	 *   be accessed
	 * @return none
	 */
	public function __call($method,$params)
	{
		// Let's cheat a bit
		$domain = FRM_Request::getAction();
		$target = FRM_Request::getArgsString();

		// Resolve path to the content, safely
		$target = $this->_root_dir.'/'.$domain.'/'.$target;
		$target = realpath($target);

		// Does it contain the base path for resources?
		if (strpos($target,$this->_root_dir) === 0)
		{
			// Is it an existing file?
			if ((is_file($target) or is_link($target)) and is_readable($target))
			{
				// That's a found, mime-type it and serve it in passthru mode
				if ($mime_type = MIME_Type::autoDetect($target))
				{
					header('Content-type: '.$mime_type);
				}

				// Pass the size
				header('Content-Length: '.filesize($target));

				$handler = fopen($target,'rb');
				fpassthru($handler);
				fclose($handler);
			}
			else
			{
				// That's a miss, typically a (404)
				// Let's throw the associated exception
				throw new FRM_Exception("File `$target` not found",FRM_Exception::NOT_FOUND);
			}
		}
		else
		{
			// Typically, access forbidden error (403)
			// Let's throw the associated exception
			throw new FRM_Exception("Access to file `$target` is forbidden",FRM_Exception::FORBIDDEN);
		}
	}
}